package cn.edu.scau.cmi.liyunlin.hibernate.dao;

import cn.edu.scau.cmi.liyunlin.hibernate.domain.Student;

import java.util.List;

import org.hibernate.LockOptions;
import org.hibernate.Query;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.Transaction;
import org.hibernate.cfg.Configuration;
import org.hibernate.criterion.Example;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;



public class StudentDao extends BaseHibernateDao {
	
	private static final Logger log = LoggerFactory.getLogger(StudentDao.class);
	// property constants
	public static final String NAME = "name";
	public static final String NUMBER = "number";

	public void save(Student transientInstance) {
		log.debug("saving Student instance");
		
		Configuration cfg = new Configuration();
		cfg.configure();
		SessionFactory factory = cfg.buildSessionFactory();
		Session session = factory.openSession();
		Transaction tx = session.beginTransaction();
		session.save(transientInstance);
		try {
			tx.commit();
		}catch(RuntimeException re) {
			log.error("save failed", re);
			throw re;
		}
		session.clear();
		session.close();
	}

	public void delete(Student persistentInstance) {
		log.debug("deleting Student instance");
		
		Configuration cfg = new Configuration();
		cfg.configure();
		SessionFactory factory = cfg.buildSessionFactory();
		Session session = factory.openSession();
		Transaction tx = session.beginTransaction();
		session.delete(persistentInstance);
		
		try {
			tx.commit();
			log.debug("delete successful");
		} catch (RuntimeException re) {
			log.error("delete failed", re);
			throw re;
		}
		session.clear();
		session.close();
	}

	public Student findById(java.lang.Long id) {
		log.debug("getting Student instance with id: " + id);
		
		Configuration cfg = new Configuration();
		cfg.configure();
		SessionFactory factory = cfg.buildSessionFactory();
		Session session = factory.openSession();
		Transaction tx = session.beginTransaction();
		
		try {
			Student instance = (Student) session.get(Student.class, id);
			session.clear();
			session.close();
			return instance;			
		} catch (RuntimeException re) {
			log.error("get failed", re);
			throw re;
		}		
	}

	public Student merge(Student detachedInstance) {
		log.debug("merging Student instance");
		
		Configuration cfg = new Configuration();
		cfg.configure();
		SessionFactory factory = cfg.buildSessionFactory();
		Session session = factory.openSession();
		Transaction tx = session.beginTransaction();
		
		try {
			Student result = (Student) session.merge(detachedInstance);
			tx.commit();
			log.debug("merge successful");
			session.clear();
			session.close();
			return result;
		} catch (RuntimeException re) {
			log.error("merge failed", re);
			throw re;
		}
	}

	public void attachDirty(Student instance) {
		log.debug("attaching dirty Student instance");
		
		Configuration cfg = new Configuration();
		cfg.configure();
		SessionFactory factory = cfg.buildSessionFactory();
		Session session = factory.openSession();
		Transaction tx = session.beginTransaction();
		//session.delete(instance);
		
		try {
			session.saveOrUpdate(instance);
			tx.commit();
			log.debug("attach successful");
		} catch (RuntimeException re) {
			log.error("attach failed", re);
			throw re;
		}
		session.clear();
		session.close();
	}

	public void attachClean(Student instance) {
		log.debug("attaching clean Student instance");
		try {
			getSession().buildLockRequest(LockOptions.NONE).lock(instance);
			log.debug("attach successful");
		} catch (RuntimeException re) {
			log.error("attach failed", re);
			throw re;
		}
	}

}
